package com.panshi.repast.Http;

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;

import org.apache.http.NameValuePair;

import android.os.Handler;
import android.os.Looper;

/**
 * 获取数据处理异步类
 * 
 * @author huang
 * 
 */
public class DataLoaderTask {

	private static DataLoaderTask mInstance = null;
	private static final int MAX_TASK_LIMIT = 3;
	private AtomicInteger mActiveTaskCount = new AtomicInteger(0);
	private final List<DataRequest> mRequests; // 传递参数
	private final Handler mDataHandler;
	// 开启网络线程池
	private ExecutorService executorService = Executors.newFixedThreadPool(3);

	/**
	 * 构造函数
	 */
	private DataLoaderTask() {
		mRequests = Collections.synchronizedList(new LinkedList<DataRequest>());
		mDataHandler = new Handler(Looper.getMainLooper());
	}

	/**
	 * 获取实列，单列模式
	 * 
	 * @return
	 */
	public static DataLoaderTask getInstance() {
		if (mInstance == null) {
			// 安全锁，保证只被实列话一次
			synchronized (DataLoaderTask.class) {
				if (mInstance == null) {
					mInstance = new DataLoaderTask();
				}
			}
		}
		return mInstance;
	}

	/**
	 * 接口 加入线程池
	 * 
	 * @param mDefValue
	 *            默认值为-1
	 * 
	 */
	public void loadData(DataCallback callback, String url,
			List<NameValuePair> params, String mDefValue) {
		DataRequest request = new DataRequest(callback, url, params, mDefValue);
		insertRequestAtFrontOfQueue(request);
	}

	/**
	 * UI更新接口，抛出数据
	 * 
	 * @param callback
	 *            接口
	 * @param url
	 *            URL地址
	 * @param params
	 *            参数
	 * 
	 */
	public void loadData(DataCallback callback, String url,
			List<NameValuePair> params) {
		loadData(callback, url, params, "-1");
	}

	/**
	 * 刷新线程池
	 */
	private synchronized void flushRequests() {
		while (mActiveTaskCount.get() < MAX_TASK_LIMIT && !mRequests.isEmpty()) {
			mActiveTaskCount.incrementAndGet();
			DataRequest request = mRequests.get(0);
			executorService.execute(new RequestTask(request));
			mRequests.remove(0);
		}
	}

	/**
	 * 线程处理数据
	 * 
	 * @author huang
	 * 
	 */
	private class RequestTask extends Thread {

		private DataRequest request;

		public RequestTask(DataRequest request) {
			this.request = request;
		}

		@Override
		public void run() {
			try {
				doInBackground();
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				handleMessage(request);
				mActiveTaskCount.decrementAndGet();
				flushRequests();
			}
		}

		/**
		 * 获取完毕
		 * 
		 * @throws Exception
		 */
		protected void doInBackground() throws Exception {
			byte[] data = null;
			if (NetworkInfoManager.isNetworkAvailable()) {
				data = HttpClientExecutor.getInstance().executePost(
						request.url, request.params);
				dealData(request, data);
			} else {
				request.dataStatus = 2;// 请检查网络
			}
		}
	}

	/**
	 * 处理获取数据
	 * 
	 * @param request
	 * @param data
	 * @throws Exception
	 */
	private void dealData(DataRequest request, byte[] data) throws Exception {
		if (data == null || data.length == 0) {
			request.dataStatus = 1;// 获取数据为空
		} else {
			String value = new String(data, "UTF-8");
			if (!value.equals("")) {
				request.mValue = value;
			}
			request.mValue = request.mValue != null ? request.mValue : "";
		}
	}

	/**
	 * 清楚数据
	 */
	public void clearDataRequests() {
		mRequests.clear();
	}

	public void shutDown() {
		// executorService.shutdown();
	}

	/**
	 * 移除DataRequest指定URL
	 * 
	 * @param url
	 */
	public synchronized void clearDataRequest(String url) {
		for (DataRequest request : mRequests) {
			if (request.url != null && request.url.contains(url)) {
				mRequests.remove(request);
			}
		}
	}

	/**
	 * 发送消息
	 * 
	 * @param DataRequest
	 * @param mValue
	 */
	private void handleMessage(final DataRequest request) {
		if (request.callback != null) {
			mDataHandler.post(new Runnable() {
				@Override
				public void run() {
					try {
						if (request.callback != null) {
							request.callback.dataCallback(request.dataStatus,
									request.mValue);
						}
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			});
		}
	}

	/**
	 * 添加进线程
	 * 
	 * @param request
	 */
	private void insertRequestAtFrontOfQueue(DataRequest request) {
		mRequests.add(0, request);
		flushRequests();
	}

	public interface DataCallback {
		// 接口
		void dataCallback(int dataStatus, String mValue);
	}

}
